package com.bub.pay.core.manager.merchant.impl;

import com.bub.pay.core.dao.*;
import com.bub.pay.core.entity.domain.SysPerm;
import com.bub.pay.core.entity.domain.SysRole;
import com.bub.pay.core.entity.domain.SysRolePerm;
import com.bub.pay.core.entity.domain.SysUserRole;
import com.bub.pay.core.entity.dto.merchant.MerchantRoleAddPermDTO;
import com.bub.pay.core.entity.dto.merchant.MerchantRoleSelectDTO;
import com.bub.pay.core.entity.vo.merchant.MerchantRoleSelectVO;
import com.bub.pay.core.entity.vo.merchant.PermsOfRoleVO;
import com.bub.pay.core.manager.merchant.MerchantRoleManager;
import com.bub.pay.framework.common.entity.model.SessionModel;
import com.bub.pay.framework.common.util.ContextHolder;
import com.bub.pay.framework.common.util.DateUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.*;


/**
 * @Description 商户角色管理
 * @Auhtor John
 */
@Service
public class MerchantRoleManagerImpl implements MerchantRoleManager {

    @Resource
    SysUserDao sysUserDao;
    @Resource
    SysRoleDao sysRoleDao;
    @Resource
    SysPermDao sysPermDao;
    @Resource
    SysUserRoleDao sysUserRoleDao;
    @Resource
    SysRolePermDao sysRolePermDao;

    @Override
    public List<SysRole> allRoles() {
        return sysRoleDao.allRoles();
    }

    @Override
    public List<MerchantRoleSelectVO> selectMerchantRole(MerchantRoleSelectDTO dto) {
        if (dto == null)
            throw new IllegalArgumentException("请求不能为空");
        List<MerchantRoleSelectVO> res = new ArrayList<>();
        Example sysRoleExample = new Example(SysRole.class);
        Example.Criteria sysRoleExampleCriteria = sysRoleExample.createCriteria();
        if (dto.getOrderByCreateDatetime() != null && dto.getOrderByCreateDatetime() == 1) {
            sysRoleExample.setOrderByClause("create_date");
        } else if (dto.getOrderByCreateDatetime() != null && dto.getOrderByCreateDatetime() == 2) {
            sysRoleExample.setOrderByClause("create_date desc");
        }
        String roleName = dto.getRoleName() == null ? "" : "%" + dto.getRoleName() + "%";
        Date startDate = dto.getCreateFirstDatetime() == null ? null : new Date(dto.getCreateFirstDatetime());
        Date endDate = dto.getCreateLastDatetime() == null ? null : new Date(dto.getCreateLastDatetime());
        if (roleName != null)
            sysRoleExampleCriteria.andLike("name", roleName);
        if (startDate != null)
            sysRoleExampleCriteria.andGreaterThanOrEqualTo("createDate", startDate);
        if (endDate != null)
            sysRoleExampleCriteria.andLessThanOrEqualTo("createDate", endDate);
        sysRoleExampleCriteria.andEqualTo("delFlag", false);
        sysRoleExampleCriteria.andEqualTo("type", 1);
        List<SysRole> sysRoles = sysRoleDao.selectByExample(sysRoleExample);
        for (SysRole sysRole : sysRoles) {
            Example sysUserRoleExample = new Example(SysUserRole.class);
            Example.Criteria sysUserRoleExampleCriteria = sysUserRoleExample.createCriteria();
            Example sysRolePermExample = new Example(SysRolePerm.class);
            Example.Criteria sysRolePermExampleCriteria = sysRolePermExample.createCriteria();
            MerchantRoleSelectVO vo = new MerchantRoleSelectVO();
            Long roleId = sysRole.getId();
            sysUserRoleExampleCriteria.andEqualTo("roleId", roleId)
                    .andEqualTo("delFlag", 0);
            sysRolePermExampleCriteria.andEqualTo("roleId", roleId)
                    .andEqualTo("delFlag", 0);

            int employeeNum = sysUserRoleDao.selectCountByExample(sysUserRoleExample);
            int permNum = sysRolePermDao.selectCountByExample(sysRolePermExample);
            vo.setRoleId(roleId);
            Date createDate = sysRole.getCreateDate();
            vo.setCreateDatetime(createDate == null ? "" : DateUtil.format(createDate, "yyyy-MM-dd HH:mm:ss"));
            vo.setRoleDescription(sysRole.getRemarks());
            vo.setRoleName(sysRole.getName());
            vo.setEmployeeNum(employeeNum);
            vo.setPermissionNum(permNum);
            res.add(vo);
        }
        return res;
    }

    @Override
    public int insertRoleSelective(SysRole role) {

        List<SysRole> roles = sysRoleDao.allRoles();
        for (SysRole r : roles) {
            if (r.getName().equals(role.getName()))
                throw new IllegalArgumentException("该角色名已存在");
        }
        role.setType(1);//商户
        int i = sysRoleDao.insertSelective(role);
        if (i < 1)
            throw new IllegalArgumentException("插入失败");
        return i;
    }

    @Override
    public int deleteRoleByPrimaryKey(Long id) {

        if (sysRoleDao.selectByPrimaryKey(id) == null)
            throw new IllegalArgumentException("不存在该角色id");

        Example example = new Example(SysRole.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("id", id);

        SysRole sysRole = new SysRole();
        sysRole.setDelFlag(true);

        int i = sysRoleDao.updateByExampleSelective(sysRole, example);
        if (i < 1)
            throw new IllegalArgumentException("删除失败");
        return i;
    }

    @Override
    public int updateRole(SysRole sysRole) {
        if (sysRole.getId() == null)
            throw new IllegalArgumentException("角色id不能为空");
        if (sysRoleDao.selectByPrimaryKey(sysRole.getId()) == null)
            throw new IllegalArgumentException("不存在该角色id");
        Example example = new Example(SysRole.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("id", sysRole.getId());
        int i = sysRoleDao.updateByExampleSelective(sysRole, example);
        if (i < 1)
            throw new IllegalArgumentException("编辑成功");
        return i;
    }

    @Override
    public List<SysPerm> getPermOfRole(Long roleId) {
        return getPermOfRoleByStatus(roleId , 0);
    }

    public List<SysPerm> getPermOfRoleContainsDeleted(Long roleId) {
        return getPermOfRoleByStatus(roleId , null);
    }

    public List<SysPerm> getPermOfRoleHasDeleted(Long roleId) {//好像有点问题
        return getPermOfRoleByStatus(roleId,1);
    }

    private List<SysPerm> getPermOfRoleByStatus(Long roleId, Integer status) {
        List<Long> permsId = new ArrayList<>();

        if (roleId == null || roleId <= 0)
            return getPermOfPlatform(1);

        Example rolePermExample = new Example(SysRolePerm.class);
        rolePermExample.setDistinct(true);
        Example.Criteria rolePermExampleCriteria = rolePermExample.createCriteria();
        rolePermExampleCriteria.andEqualTo("roleId", roleId);
        if (status != null && status == 0)
            rolePermExampleCriteria.andEqualTo("delFlag", false);
        if (status != null && status == 1)
            rolePermExampleCriteria.andEqualTo("delFlag", true);
        List<SysRolePerm> sysRolePerms = sysRolePermDao.selectByExample(rolePermExample);
        for (SysRolePerm rolePerm : sysRolePerms) {
            permsId.add(rolePerm.getPermId());
        }
        Example permExample = new Example(SysPerm.class);
        Example.Criteria permExampleCriteria = permExample.createCriteria();
        if (permsId.size() == 0) {
            return null;
        }
        permExampleCriteria.andEqualTo("platformType", 1).andIn("id", permsId);
        List<SysPerm> sysPerms = sysPermDao.selectByExample(permExample);
        return sysPerms;
    }

    @Override
    public List<SysPerm> getPermOfPlatform(Integer platformId) {
        Example permExample = new Example(SysPerm.class);
        Example.Criteria permExampleCriteria = permExample.createCriteria();
        permExampleCriteria.andEqualTo("platformType", platformId)
                .andEqualTo("delFlag", false);
        List<SysPerm> allPlatformPerm = sysPermDao.selectByExample(permExample);
        return allPlatformPerm;
    }

    @Override
    public List<PermsOfRoleVO> getPermsOfRoleIsContainsInPlatformAllPerms(Long roleId) {
        List<PermsOfRoleVO> res = new ArrayList<>();
        List<SysPerm> permOfPlatform = getPermOfPlatform(1);
        List<SysPerm> permOfRole = getPermOfRole(roleId);
        List<Long> permIds = new ArrayList<>();
        for(SysPerm perm : permOfRole){
            permIds.add(perm.getId());
        }
        for(SysPerm perm : permOfPlatform){
            PermsOfRoleVO vo = new PermsOfRoleVO();
            vo.setPermId(perm.getId());
            vo.setPermName(perm.getName());
            vo.setParentId(perm.getParentId());
            vo.setHasPerm(permIds.contains(perm.getId()));
            res.add(vo);
        }
        return res;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public int setPermForRole(MerchantRoleAddPermDTO dto) {

        SessionModel sessionModel = ContextHolder.currentUserInfo();
        String[] ss = dto.getPermIds().split(",");
        List<String> inputIds = Arrays.asList(ss);
        List<Long> inputPermIds = new ArrayList<>();
        for (String inputId : inputIds) {
            if (!"".equals(inputId)) {
                try {
                    inputPermIds.add(Long.parseLong(inputId));
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException("权限id格式错误");
                }
            }
        }
        List<SysPerm> permOfRole = getPermOfRole(dto.getRoleId());
        List<SysPerm> permOfRoleContainsDeleted = getPermOfRoleContainsDeleted(dto.getRoleId());
        // 该角色已经存在的所有的权限id集合(不包括已经删除的)
        List<Long> existPermIds = new ArrayList<>();
        if (permOfRole != null) {
            for (SysPerm perm : permOfRole) {
                existPermIds.add(perm.getId());
            }
        }
        // 该角色所有的权限id集合(包括已经删除的)
        List<Long> allPermIdsContainsDeleted = new ArrayList<>();
        if (permOfRoleContainsDeleted != null) {
            for (SysPerm perm : permOfRoleContainsDeleted) {
                allPermIdsContainsDeleted.add(perm.getId());
            }
        }

        // 该角色删除了的权限id集合
        List<Long> deletedPermIds = new ArrayList<>();
        for (Long permId : allPermIdsContainsDeleted) {
            if (!existPermIds.contains(permId)) {
                deletedPermIds.add(permId);
            }
        }

        //输入的有效权限id集合(要添加的id集合)
        List<Long> addPermIds = new ArrayList<>();
        for (Long permId : inputPermIds) {
            if (!existPermIds.contains(permId)) {//已经存在的权限id忽略不计
                if (!addPermIds.contains(permId)) {
                    addPermIds.add(permId);
                }
            }
        }
        //要删除的权限id集合
        List<Long> deletePermIds = new ArrayList<>();
        for (Long permId : existPermIds) {
            if (!inputPermIds.contains(permId)) {//输入的权限id中不包含角色已经存在的，即为删除
                if (!deletePermIds.contains(permId)) {
                    deletePermIds.add(permId);
                }
            }

        }
        List<SysPerm> allPlatformPerms = getPermOfPlatform(1);
        //该平台所有的权限id集合
        List<Long> allPlatformPermIds = new ArrayList<>();
        for (SysPerm sysPerm : allPlatformPerms) {
            allPlatformPermIds.add(sysPerm.getId());
        }
        if (!allPlatformPermIds.containsAll(addPermIds))
            throw new IllegalArgumentException("超出可添加权限范围");
        int i = 0;
        Date now = new Date();
        SysRolePerm rolePerm = new SysRolePerm();
        rolePerm.setRoleId(dto.getRoleId());
        rolePerm.setUpdateDate(now);
        rolePerm.setUpdateId(sessionModel.getUserId());
        rolePerm.setDelFlag(false);
        if (addPermIds.size() != 0) {
            for (Long permId : addPermIds) {
                if (!deletedPermIds.contains(permId)) {
                    rolePerm.setId(null);
                    rolePerm.setPermId(permId);
                    rolePerm.setCreateDate(now);
                    rolePerm.setCreateId(sessionModel.getUserId());
                    i = sysRolePermDao.insertSelective(rolePerm);
                    if (i < 1)
                        throw new IllegalArgumentException("添加失败");
                } else {
                    Example example = new Example(SysRolePerm.class);
                    example.createCriteria().andEqualTo("permId", permId).andEqualTo("roleId",dto.getRoleId());
                    i = sysRolePermDao.updateByExampleSelective(rolePerm, example);
                    if (i < 1)
                        throw new IllegalArgumentException("添加失败");
                }
            }
        }
        if (deletePermIds.size() != 0) {
            SysRolePerm deleteRolePerm = new SysRolePerm();
            deleteRolePerm.setDelFlag(true);
            Example example = new Example(SysRolePerm.class);
            example.createCriteria().andEqualTo("delFlag", false).andIn("permId", deletePermIds);
            i = sysRolePermDao.updateByExampleSelective(deleteRolePerm, example);
            if (i < 1)
                throw new IllegalArgumentException("删除失败");
        }
        return i;
    }
}
